﻿//--------------------------------------------------------------------------
// 
//  Copyright (c) Chili Software.  All rights reserved. 
// 
//  File: DynamicType.cs
//
//  Description: A list of items for a DynamicProperty.
// 
//--------------------------------------------------------------------------

using System;
using System.Reflection;
using System.Xml;
using System.Collections;
using System.Collections.Generic;

namespace Chili.Opf3.DynamicProperties
{
	/// <summary>
	/// A DynamicType is a collection of values - like an enumeration. 
	/// </summary>
	/// <remarks>
	/// The advantage of a DynamicType is the possibility to create it on the fly.
	/// DynamicTypes are usually used in combination with 
	/// <see cref="Opf3.DynamicProperties.DynamicProperty">DynamicProperties</see>.
	/// When setting a DyanmicType as type of a <see cref="Opf3.DynamicProperties.DynamicProperty">DynamicProperty</see>
	/// the <see cref="Opf3.DynamicProperties.DynamicProperty">DynamicProperty</see>
	/// can only take values of the DynamicType as value.
	/// </remarks>
	/// <example>
	/// The following example shows how to use a DynamicType in combination with a 
	/// <see cref="Opf3.DynamicProperties.DynamicProperty">DynamicProperty</see>.
	/// <code lang="CS">
	/// // ... Other code
	/// 
	/// DynamicType type = new DynamicType();
	/// type.Values.Add("small");
	/// type.Values.Add("medium");
	/// type.Values.Add("large");
	/// 
	/// // Create a DynamicProperty using a DynamicType.
	/// DynamicProperty prop1 = 
	///		new DynamicProperty("Size", typeof(string), type);
	/// prop1.Value = "small";
	/// 
	/// // Throws an exception, since not in the DynamicType.
	/// prop1.Value = "bigger";
	/// 
	/// // ... Other code
	/// </code>
	/// </example>
	[Serializable]
	public sealed class DynamicType : ICloneable
	{
		private string _name;
		private List<string> _values = new List<string>();

		/// <summary>
		/// Creates a new instance of the <see cref="DynamicType">DynamicType Class</see>.
		/// This constructor is required for webservices.
		/// </summary>
		internal DynamicType()
		{
		}

		/// <summary>
		/// Creates a new instance of the <see cref="DynamicType">DynamicType Class</see>.
		/// </summary>
		/// <param name="name">Name of the <see cref="DynamicType">DynamicType</see>.</param>
		/// <exception cref="ArgumentNullException">Name is null.</exception>
		public DynamicType(string name)
		{
			if (name == null)
				throw new ArgumentNullException("name");
			_name = name;
		}

		/// <summary>
		/// Returns the name of the <see cref="DynamicType">DynamicType</see>.
		/// </summary>
		/// <value>A string that represents the name of the <see cref="DynamicType">DynamicType</see>.</value>
		public string Name
		{
			get { return _name; }
			set 
			{
				if (value == null)
					throw new ArgumentNullException("value");
				_name = value;  
			}
		}

		/// <summary>
		/// Specifies the values of the <see cref="DynamicType">DynamicType</see>.
		/// </summary>
		/// <value>A list of values of the <see cref="DynamicType">DynamicType</see>.</value>
		public List<string> Values
		{
			get { return _values; }
		}

		#region ICloneable Members

		/// <summary>
		/// Creates a new object that is a copy of the current instance.
		/// </summary>
		/// <returns>A new object that is a copy of this instance.</returns>
		public object Clone()
		{
			DynamicType dynamicType = new DynamicType(Name);
			foreach (string value in Values)
				dynamicType.Values.Add(value);

			return dynamicType;
		}

		#endregion
	}
}
